Skip to content

fix(ci): install a Rust toolchain in the bump-version jobs - #653

Merged
logbie merged 4 commits into
mainfrom
claude/main-branch-ci-failure-gdmqkg
Jul 27, 2026
Merged

fix(ci): install a Rust toolchain in the bump-version jobs#653
logbie merged 4 commits into
mainfrom
claude/main-branch-ci-failure-gdmqkg

Conversation

@logbie

@logbie logbie commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

What's broken

Every push to main since 2026-07-26 has produced a red CI run — four in a row (ed704e6a #646, 7937a53b #649, f903e8e0 #650, 48c46423 #652) — while all seven build/test jobs stayed green. The only failing job each time is Bump Version:

error: rustc 1.92.0 is not supported by the following packages:
  sqlx@0.9.0 requires rustc 1.94.0
  ...
  wfl@26.7.53 requires rustc 1.94
Error: locked fuzz check failed after bump; refusing to stage a broken fuzz/Cargo.lock

Side effect: the bump never landed, so main is stuck at version 26.7.52 and no v* tags were pushed for those four commits.

Root cause

bump-version runs python scripts/bump_version.py --update-all, which shells out to Cargo three times — cargo update --package wfl for the root lock, the same for fuzz/Cargo.lock, and finally cargo check --locked --manifest-path fuzz/Cargo.toml as a guard so a bump can never stage a fuzz lock that the fuzz-check gate would then reject.

The job never installed a toolchain. Every other Cargo-running job in this repo uses dtolnay/rust-toolchain@stable; this one silently inherited whatever rustc the runner image preinstalled. That worked on GitHub-hosted images and stopped working the moment CI moved to Blacksmith runners (#646), whose ubuntu-2404 image ships rustc 1.92.0 — below our rust-version = "1.94" (raised by the sqlx 0.9 dependency).

It was easy to miss because the Cargo dependency is invisible in the workflow file — it hides behind a Python script, so scanning ci.yml for cargo finds nothing in this job. #646 only changed the job's runs-on: label.

The fix

  • .github/workflows/ci.yml — add dtolnay/rust-toolchain@stable before the bump step, plus a restore-only Swatinem/rust-cache sharing fuzz-check's fuzz-check-cache key so the locked fuzz check reuses that job's build instead of recompiling the workspace on every push to main.
  • .github/workflows/versioning.yml — the manual-dispatch bump-version job has the identical latent defect and would fail the same way the next time anyone triggered it. Same one-line fix.

Deliberately not changed: the cargo check --locked guard inside bump_version.py. It did exactly its job — it caught a broken environment and refused to commit a lockfile it could not verify. Relaxing it would trade a loud failure for a silently stale fuzz/Cargo.lock.

Test evidence

  • Risk class: R1 — build/release tooling; no runtime or language behavior changes, no public contract touched.

  • Acceptance criteria → tests (all in tests/workflow_rust_toolchain_test.rs):

    Acceptance criterion Test
    Every job that runs Cargo — directly or via a scripts/*.py indirection — installs a toolchain before the first Cargo use cargo_jobs_install_a_rust_toolchain_first
    The Cargo-invoking script inventory cannot silently go stale cargo_invoking_scripts_list_is_complete
    Comment-only cargo mentions are ignored; real jobs are still found scanner_ignores_comments_and_finds_jobs
    Only genuine setup counts — echo rust-toolchain and rustup target/component add do not toolchain_markers_reject_incidental_mentions
    Cargo-argv detection survives whitespace/quote/multi-line reformatting script_cargo_detection_tolerates_whitespace_and_argv_forms
    A toolchain installed after the first Cargo step is out of order, not satisfying toolchain_after_cargo_is_out_of_order
  • Red evidence: commit 2ab115d is test-only and an ancestor of the fix. It fails there for the intended reason — before any workflow edit existed:

    no toolchain step: ["ci.yml:bump-version", "versioning.yml:bump-version"]
    

    It caught the versioning.yml instance too, which nobody had reported. After the scanner was tightened in review, it was re-checked against the original defect: removing the toolchain step from ci.yml again fails the guard with no toolchain step: ["ci.yml:bump-version"], so the hardening did not cost it its bite.

  • Unit/component: cargo test --test workflow_rust_toolchain_testok. 6 passed; 0 failed (rustc 1.94.1).

  • Lint/format: cargo fmt --all -- --check clean; cargo clippy --all-targets --all-features -- -D warnings clean.

  • Full workspace suite: CI run 30240210815 on this branch — Build, Test, Clippy green including its Run Tests step, plus integration, database, fuzz-compile and WFL-program jobs on Linux and Windows. A local cargo test --all was attempted but exhausted the authoring container's disk allowance mid-link (a Bus error from the ~30 GB target/ tree documented in CLAUDE.md) — an environment limit, not a test failure; CI runners carry the Free disk space step the container lacks.

  • End-to-end / real boundary: cargo check --locked --manifest-path fuzz/Cargo.toml — the exact command that failed in CI — run locally on rustc 1.94.1: exit 0, Finished dev profile in 2m 04s.

  • Coverage: the guard covers all 8 workflow files and every job in them; it flagged 2 of the 11 Cargo-using jobs and passes on all 11 after the fix.

  • Platforms: the fixed jobs run on blacksmith-4vcpu-ubuntu-2404; the guard itself is platform-independent (static file analysis).

  • Not applicable, with reason: no §11.3 concurrency/streaming/lifecycle tests — this change adds a CI setup step and touches no runtime code, async path, or untrusted input. No docs-example validation — no user-facing syntax, stdlib, CLI flag, or config option changed.

  • Rollback/recovery: revert this PR; CI returns to its current (red Bump Version) state, no external state to unwind. After merge the bump job resumes from 26.7.52 and pushes the next version + tag normally.

  • Residual risk: the guard is a line scanner, not a YAML parse (the repo carries no YAML dependency), so it assumes job ids are the only two-space-indented keys under jobs: — true for all current workflows and asserted by a scanner self-test. It cannot see Cargo invoked from a shell script or a composite action; only scripts/*.py indirection is resolved.

Note on verification limits: bump-version is gated on github.event_name == 'push' && github.ref == 'refs/heads/main', so it cannot run on this PR (it shows as skipped). This PR's CI proves nothing regressed; the definitive proof of the fix is the Bump Version job on the post-merge push to main.

Dev Diary: Dev diary/2026-07-27-ci-bump-version-toolchain.md.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sfkzn8nZgGEddsoYWAf3BC

claude added 2 commits July 27, 2026 05:31
Red evidence for the main-branch CI failure. The `bump-version` job in
ci.yml runs `python scripts/bump_version.py --update-all`, which shells
out to `cargo update` and `cargo check --locked --manifest-path
fuzz/Cargo.toml`, but never installs a Rust toolchain — it inherits
whatever rustc the runner image ships.

This test scans every workflow job, resolves the Python-script
indirection, and asserts a toolchain is installed before the first cargo
use. It currently fails on ci.yml:bump-version and
versioning.yml:bump-version.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sfkzn8nZgGEddsoYWAf3BC
`bump_version.py` shells out to Cargo — `cargo update` for the root and
fuzz lockfiles, then `cargo check --locked --manifest-path
fuzz/Cargo.toml` as a guard against staging a fuzz lock the `fuzz-check`
gate would reject. Neither `bump-version` job installed a toolchain, so
both inherited whatever rustc the runner image preinstalled.

That held until CI moved to Blacksmith runners (#646), whose ubuntu-2404
image ships rustc 1.92.0 — below `rust-version = "1.94"` (raised by sqlx
0.9). The locked fuzz check failed, the bump refused to stage, and every
push to main went red while all seven build/test jobs stayed green. main
has been stuck at 26.7.52 with no tags pushed since.

Add `dtolnay/rust-toolchain@stable` before the bump step in both jobs, as
every other Cargo-running job in the repo already does. ci.yml also gets
a restore-only rust-cache sharing the `fuzz-check` job's key so the
locked check reuses that build instead of recompiling the workspace.

The guard inside bump_version.py is left alone — it correctly refused to
commit a lockfile it could not verify.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sfkzn8nZgGEddsoYWAf3BC
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The bump-version workflows now install stable Rust and restore the fuzz Cargo cache before running version updates. New Rust tests scan workflows to enforce toolchain ordering for direct and indirect Cargo usage.

Changes

Version-bump toolchain enforcement

Layer / File(s) Summary
Workflow toolchain and cache setup
.github/workflows/ci.yml, .github/workflows/versioning.yml, Dev diary/...
Both bump-version jobs install stable Rust; CI also restores the fuzz workspace cache. The incident record documents the MSRV failure, fix, and verification.
Workflow scanner tests
tests/workflow_rust_toolchain_test.rs
Tests discover workflow jobs, detect direct or Python-mediated Cargo usage, require an earlier toolchain step, validate the indirection list, and ignore comments.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: installing a Rust toolchain in the bump-version jobs to fix CI.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/main-branch-ci-failure-gdmqkg

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Dev` diary/2026-07-27-ci-bump-version-toolchain.md:
- Around line 17-23: Update both fenced output blocks in the diary entry to
specify the text language on their opening fences, changing each unannotated
fence to ```text while preserving the existing contents.
- Around line 71-94: Update the “Testing (Logbie Testing Policy)” section to
explicitly map acceptance criteria to tests and record the required validation
evidence: formatting check, warnings-denied Clippy, and full verbose Cargo test
commands with their exact results. Include explicit Red/Green commit evidence
and preserve the existing risk class, boundary validation, and residual-risk
details.

In `@tests/workflow_rust_toolchain_test.rs`:
- Around line 26-27: Replace the broad TOOLCHAIN_MARKERS substring checks with
matching for genuine Rust toolchain setup/selection commands, excluding echo
text and unrelated rustup subcommands such as target additions. Extend the
script inventory detection to recognize Cargo invocations, including subprocess
argv forms and varied whitespace. Add regression fixtures covering whitespace
and alternate argv formatting, and ensure tests exercise the scanner’s actual
command-boundary logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f9e5ef0-5947-42e1-93a2-e13a3d429651

📥 Commits

Reviewing files that changed from the base of the PR and between 48c4642 and 41dfc53.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/versioning.yml
  • Dev diary/2026-07-27-ci-bump-version-toolchain.md
  • tests/workflow_rust_toolchain_test.rs

Comment thread Dev diary/2026-07-27-ci-bump-version-toolchain.md Outdated
Comment thread Dev diary/2026-07-27-ci-bump-version-toolchain.md
Comment thread tests/workflow_rust_toolchain_test.rs Outdated
logbie and others added 2 commits July 27, 2026 05:46
…ry evidence

- Match real toolchain setup (action refs, rustup install/default/override)
  instead of loose rust-toolchain/rustup substrings, so echo/target-add mentions
  no longer satisfy the guard.
- Make the script Cargo-argv detector whitespace- and quote-tolerant via
  whitespace collapse, and add regression fixtures for both.
- Fill in the dev diary Testing section: acceptance-criteria->tests mapping,
  fmt/clippy/test validation evidence, and text-annotated fenced blocks.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
The ordering half of the guard's contract — a toolchain step must come
*before* the first Cargo use — was asserted by the main scan but never
exercised by a fixture, so a regression in the comparison would have gone
unnoticed. Add `toolchain_after_cargo_is_out_of_order` covering both the
late and early arrangements.

Also record verified evidence in the dev diary: re-running the tightened
scanner against a temporarily toolchain-less ci.yml still reproduces the
original defect, and the validation block now carries the numbers
actually observed on rustc 1.94.1 plus the CI run that covers the full
workspace suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sfkzn8nZgGEddsoYWAf3BC
@logbie
logbie merged commit 752fbf4 into main Jul 27, 2026
17 checks passed
@logbie
logbie deleted the claude/main-branch-ci-failure-gdmqkg branch July 27, 2026 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants